<template>
  <div
    class="tr-rating"
    v-show="mappingProps.visible"
    :class="{
      'z-mobile': isMobile,
      'z-vertical':
        mappingProps.labelPosition == 'top' && !mappingProps.hideLabel,
    }"
    tabindex="-1"
  >
    <LabelPrefixWraper
      v-show="mappingProps.visible"
      :labelProps="{ class: 'label-title' }"
      :label="mappingProps.label"
      :hideLabel="mappingProps.hideLabel"
      :labelPosition="labelPosition"
      :helpConf="mappingProps.helpConf"
      :helpTooltip="mappingProps.helpTooltip"
      :helpPlacement="mappingProps.helpPlacement"
      :helpMore="mappingProps.helpMore"
      :helpMorePopup="mappingProps.helpMorePopup"
      :helpMoreLink="mappingProps.helpMoreLink"
      :helpMoreLinkHrefStatic="mappingProps.helpMoreLinkHrefStatic"
      :helpMoreLinkHrefExp="mappingProps.helpMoreLinkHrefExp"
      :required="mappingProps.required"
      tabindex="-1"
    >
    </LabelPrefixWraper>

    <div class="tr-rating-value">
      <div class="tr-rating-cnt">
        <Rating
          :icon="mappingProps.icon"
          :color="color"
          :size="mappingProps.size || '20px'"
          :max="parseInt(mappingProps.max)"
          :noReset="mappingProps.noReset"
          :disable="mappingProps.disable"
          :readonly="mappingProps.readonly"
          :tabindex="mappingProps.tabIndex"
          v-model="mappingProps.modelValue"
          @click="onClickHandler"
        >
        </Rating>

        <!-- 辅助文字 -->
        <span
          class="tr-rating-helptext"
          v-show="
            mappingProps.showText && helpTextList[mappingProps.modelValue - 1]
          "
          >{{ helpTextList[mappingProps.modelValue - 1] }}</span
        >
      </div>

      <!-- 必填校验显示 -->
      <div v-if="displayedRequiredError" class="u-error-message">
        {{ mappingProps.requiredMessage }}
      </div>
    </div>
  </div>
</template>

<!-- ts只是方便开发提示和补全代码，没有用语法 -->

<script setup type="typescript">
import { computed, ref, useAttrs, watch } from 'vue';
// 钩子方法
import { useFormChild, useQuasar } from '@teld/q-components';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
	commonProps
} from 't/common/utils';
// 组件
import Rating from '@teld/q-components/Rating';
import LabelPrefixWraper from '../label-prefix-wraper';


const $q = useQuasar();
// 浏览宽度低于768px
const isMobile = computed(() => $q.screen.xs || $q.platform.is.mobile);

// 直接映射透传qursor的属性
const attrs = useAttrs();
// 组件传参
const props = defineProps(
	{
		...commonProps,
		...Rating.props,
		...LabelPrefixWraper.props,
		label: {
			type: String,
			default() {
				return '';
			},
		},
		required: {
			type: Boolean,
			default() {
				return false;
			},
		},
		requiredMessage: {
			type: String,
			default() {
				return '';
			},
		},
		// 图标字体大小
		icon: {
			type: String,
			default: 'fas dx-icon icon-t-star-fill',
		},
		// 图标字体大小
		size: {
			type: String,
			default: '20px',
		},
		// 辅助文字(用,隔开)
		texts: {
			type: String,
			default() {
				return '';
			},
		},
		showText: {
			type: Boolean,
			default() {
				return false;
			},
		},
		max: {
			type: [Number, String],
			default() {
				return 5;
			},
		},

		// 选中颜色
		color: {
			type: String,
		},

		tabIndex: {
			type: [String, Number],
			default() {
				return 0;
			},
		},
	},
);
// 大写首字母属性
const [mappingProps, mappingExpose] = useMappingProps(props);

// ============================= 颜色配置：quasar不支持hex颜色，需要转换成class形式  ===========================
// prop传参color，强制转换为字符串
const propColorArray = computed(() => (typeof mappingProps.color == 'string' ? mappingProps.color : 'teld_primary').split(','));
// 从props的color配置，返回quasar所需要的颜色代码(string/array)
const color = computed(() => {
	const color_array = propColorArray.value;
	if (color_array.length == 0) return 'teld_primary';
	const [color_1] = color_array;
	if (color_array.length == 1) return (!color_1 || color_1 === 'default') ? 'teld_primary' : color_1;
	console.log('color_array', color_array)
	return color_array;
})


// ============================= label 位置  ===========================
const labelPosition = computed(() => {
	if (isMobile.value) {
		return 'top';
	}
	return mappingProps.labelPosition;
});

// ============================= 辅助文字相关 ===========================
const helpTextList = computed(() => {
	const { max, texts } = mappingProps;
	const textArray = texts.split(',');
	return new Array(max).fill('').map((v, i) => textArray[i] || v)
})

// ============================= 必填校验相关 ===========================
// 是否显示必填校验错误
const displayedRequiredError = ref(false);
// 必填校验，不能选0
function validate() {
	const { required, modelValue, requiredMessage } = mappingProps;
	const value = modelValue;
	displayedRequiredError.value = required && (typeof value == 'undefined' || value == null || value == 0)
	return !displayedRequiredError.value
}
// 应该返回一个布尔值（或一个 resolve 布尔值的 Promise）
function resetValidation() {
	displayedRequiredError.value = false;
}

// ============================= 暴漏外部方法 ===========================
defineExpose({ ...mappingExpose, resetValidation, validate });

// 与qForm组件通信，校验用户输入是否合法
useFormChild({
	validate, // 函数；可以是异步的；
	resetValidation, // 可选的函数，可重置验证
	requiresQForm: false // 如果没有找到父级 QForm，它是否应该报错？
});

// ============================= 回调事件 ===========================
// 触发的emit事件
const emit = defineEmits(['click', 'change', 'update:modelValue']);

// 点击事件
function onClickHandler(params) {
	emit('click', params)
}

// 评分改变回调
watch(
	() => mappingProps.modelValue,
	(value, oldValue) => {
		if (value === oldValue) return;
		// 如果已经报了必填错误，更改时校验下
		if (displayedRequiredError.value) validate();

		// 实现本组件的 v-model
		emit('update:modelValue', value)
		// change回调
		emit('change', value)
	}
)
</script>

<style lang="scss">
@import './index.scss';
</style>
